#include "FaceDetector.h"
#include "highgui.h"
#include <iostream>

// #define DISPLAY_IN_WINDOW

using namespace std;

FaceDetector::FaceDetector(string imageName) {
	image = cvLoadImage(imageName.c_str());
}

FaceDetector::~FaceDetector() {
	cvReleaseImage(&image);
}

vector<Rect*> FaceDetector::getFaces() {
	
	// Create memory for calculations
	static CvMemStorage* storage = 0;

	// Create a new Haar classifier
	static CvHaarClassifierCascade* cascade = 0;
	cascade = (CvHaarClassifierCascade*)cvLoad("../util/cascades/haarcascade_frontalface_alt.xml");

	// Read scale
	int scale = 1;
	
#ifdef DISPLAY_IN_WINDOW
	// Create a new image based on the input image
	IplImage* temp = cvCreateImage(cvSize(image->width/scale, image->height/scale), 8, 3 );
	
	// Create a new named window with title: result
	cvNamedWindow("result", 1);
#endif
	
	// Create result array
	vector<Rect*> result;

	// Create two points to represent the face locations
	CvPoint pt1, pt2;
	
	// Check whether the cascade has loaded successfully. Else report and error and quit
	if(!cascade) {
		cout << "ERROR: Could not load classifier cascade" << endl;
		return result;
	}
	
	// Allocate the memory storage
	storage = cvCreateMemStorage(0);

	// Clear the memory storage which was used before
	cvClearMemStorage(storage);

	// There can be more than one face in an image. So create a growable sequence of faces.
	// Detect the objects and store them in the sequence
	CvSeq* faces = cvHaarDetectObjects(image, cascade, storage, 1.1, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(40, 40));
	
	// Loop the number of faces found.
	for(int i = 0; i < (faces ? faces->total : 0); i++ ) {
		
		// Create a new rectangle for drawing the face
		CvRect* r = (CvRect*)cvGetSeqElem( faces, i );

		// Find the dimensions of the face,and scale it if necessary
		pt1.x = r->x*scale;
		pt2.x = (r->x+r->width)*scale;
		pt1.y = r->y*scale;
		pt2.y = (r->y+r->height)*scale;
		
		// Create rect
		Rect* rect = new Rect(Point(r->x * scale, r->y * scale), Point((r->x + r->width) * scale, (r->y + r->height) * scale));
		result.push_back(rect);

		// Draw the rectangle in the input image
		cvRectangle(image, pt1, pt2, CV_RGB(255,0,0), 3, 8, 0 );
	}
	
	
#ifdef DISPLAY_IN_WINDOW
    // Show the image in the window named "result"
    cvShowImage("result", image);
	
	// Release the temp image created.
	cvReleaseImage(&temp);
	
	cvWaitKey();
	
	cvDestroyWindow("result");
#endif
	
	return result;
}